package me.zhengjie.config

import com.alibaba.fastjson.serializer.SerializerFeature
import com.alibaba.fastjson.support.config.FastJsonConfig
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
import me.zhengjie.common.config.FileProperties
import me.zhengjie.common.config.FileProperties.ElPath
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.MediaType
import org.springframework.http.converter.HttpMessageConverter
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
import org.springframework.web.cors.CorsConfiguration
import org.springframework.web.cors.UrlBasedCorsConfigurationSource
import org.springframework.web.filter.CorsFilter
import org.springframework.web.servlet.config.annotation.EnableWebMvc
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
import java.nio.charset.StandardCharsets
import java.text.SimpleDateFormat
import java.util.*

/**
 * WebMvcConfigurer
 *
 * @author Kuki Wu
 * @date 2024-11-30
 */
@Configuration
@EnableWebMvc
class ConfigurerAdapter(private val properties: FileProperties) : WebMvcConfigurer {

    @Bean
    fun corsFilter(): CorsFilter? {
        val source = UrlBasedCorsConfigurationSource()
        val config = CorsConfiguration()
        config.allowCredentials = true
        config.addAllowedOriginPattern("*")
        config.addAllowedHeader("*")
        config.addAllowedMethod("*")
        source.registerCorsConfiguration("/**", config)
        return CorsFilter(source)
    }

    override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
        val path: ElPath = properties.getPath()!!
        val avatarUtl = "file:" + path.avatar!!.replace("\\", "/")
        val pathUtl = "file:" + path.path!!.replace("\\", "/")
        //配置完静态资源映射路径后，需要到SecurityConfig中配置访问权限
        registry.addResourceHandler("/avatar/**").addResourceLocations(avatarUtl).setCachePeriod(0)
        registry.addResourceHandler("/file/**").addResourceLocations(pathUtl).setCachePeriod(0)
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/")
        registry.addResourceHandler("/web/**").addResourceLocations("classpath:/templates/")
        registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/").setCachePeriod(0)
    }


//    override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
//        val avatarUtl = "file:" + avatar!!.replace("\\", "/")
//        val pathUtl = "file:" + path!!.replace("\\", "/")
//        var path: File? = null
//        try {
//            path = File(ResourceUtils.getURL("classpath:").path)
//        } catch (e: FileNotFoundException) {
//            e.printStackTrace()
//        }
//        var uploadFilepathUtl = "file:///"
//        // String uploadFilepathUtl =  path.getParent() + File.separator + "strain_uploadfiles" + File.separator;
//        //String uploadFilepathUtl = "file:" + uploadfiles.replace("\\", "/");
//        //------生产环境居然会有问题，直接在D盘创建固定目录算了
//        /*if(flag.equals("dev")){
//            uploadFilepathUtl = uploadFilepathUtl + path.getParentFile().getParentFile().getParent() + File.separator + "public" + File.separator + "uploadfiles" + File.separator;
//        }else {
//            uploadFilepathUtl = uploadFilepathUtl + path.getParent() + File.separator + "public" + File.separator + "uploadfiles" + File.separator;
//        }*/
//
//        //配置server虚拟路径，handler为jsp中访问的目录，locations为files相对应的本地路径
//        //registry.addResourceHandler("/uploadfiles/**").addResourceLocations("file:///D:/omdd_fileuploads/");
//        uploadFilepathUtl += jarFilePath + File.separator + "omdd_fileuploads" + File.separator
//        registry.addResourceHandler("/uploadfiles/**").addResourceLocations(uploadFilepathUtl)
//        //registry.addResourceHandler("/public/uploadfiles/**").addResourceLocations("file:D:/omdd_fileuploads/");
//        registry.addResourceHandler("/public/uploadfiles/**").addResourceLocations(uploadFilepathUtl)
//        registry.addResourceHandler("/**")
//            .addResourceLocations(
//                "classpath:/META-INF/resources/",
//                "classpath:/resources/",
//                "classpath:/resources/main",
//                "/resources/main/",
//            ).setCachePeriod(0)
//        //registry.addResourceHandler("/**").addResourceLocations("/resources/").setCachePeriod(0)
//        registry.addResourceHandler("/avatar/**").addResourceLocations(avatarUtl).setCachePeriod(0)
//        registry.addResourceHandler("/file/**").addResourceLocations(pathUtl).setCachePeriod(0)
//        // registry.addResourceHandler("/uploadfiles/**").addResourceLocations(uploadFilepathUtl).setCachePeriod(0);
//        //registry.addResourceHandler("/public/uploadfiles/**").addResourceLocations(uploadFilepathUtl);
//    }

//    override fun configureMessageConverters(converters: MutableList<HttpMessageConverter<*>?>) {
//        // 使用 fastjson 序列化，会导致 @JsonIgnore 失效，可以使用 @JSONField(serialize = false) 替换
//        val converter = FastJsonHttpMessageConverter()
//        val supportMediaTypeList: MutableList<MediaType> = ArrayList()
//        supportMediaTypeList.add(MediaType.APPLICATION_JSON)
//        val config = FastJsonConfig()
//        config.dateFormat = "yyyy-MM-dd HH:mm:ss"
//        config.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect)
//        converter.fastJsonConfig = config
//        converter.supportedMediaTypes = supportMediaTypeList
//        converter.defaultCharset = StandardCharsets.UTF_8
//        converters.add(converter)
//    }

    override fun configureMessageConverters(converters: MutableList<HttpMessageConverter<*>>) {
        // 创建并配置 Jackson 转换器
        val converter = MappingJackson2HttpMessageConverter()

        // 配置 ObjectMapper
        val objectMapper = ObjectMapper()
        objectMapper.registerKotlinModule() // 支持 Kotlin 数据类
        objectMapper.registerModule(JavaTimeModule()) // 支持 Java 8 时间类型
        objectMapper.setDateFormat(SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
        objectMapper.configure(com.fasterxml.jackson.databind.SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
        objectMapper.configure(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
        objectMapper.configure(
            com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS,
            false
        )
        objectMapper.configure(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        objectMapper.configure(com.fasterxml.jackson.databind.DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
        objectMapper.configure(
            com.fasterxml.jackson.databind.DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE,
            false
        )

        converter.objectMapper = objectMapper

        // 设置支持的媒体类型
        val supportedMediaTypes: MutableList<MediaType> = ArrayList()
        supportedMediaTypes.add(MediaType.APPLICATION_JSON)
        converter.supportedMediaTypes = supportedMediaTypes

        // 设置默认字符集
        converter.defaultCharset = StandardCharsets.UTF_8

        // 添加转换器到列表
        converters.add(converter)
    }

}
